package mongo

import "fmt"

const (
	F_STRING   = "string"
	F_INT      = "int64"
	F_BOOL     = "bool"
	F_FLOAT    = "float64"
	F_TIME     = "time.Time"
	F_A_INT    = "[]int64"
	F_A_FLOAT  = "[]float64"
	F_A_STRING = "[]string"
	F_O2M      = "[]*"
	F_O2O      = "*"
	F_PIC      = "*ez.Pic"
	F_PICS     = "*ez.Pics"
	F_FILE     = "*ez.File"
	F_FILES    = "*ez.Files"
)

type Field struct {
	Name   string
	CnName string
	ReName string
	Type   string
	Desc   string
	Note   string

	//Join
	JoinDir    string
	JoinDoc    string
	JoinType   string
	KeyInside  string
	KeyOutSide string
}

func (this *Field) GetName() string           { return this.Name }
func (this *Field) SetName(v string) *Field   { this.Name = v; return this }
func (this *Field) GetCnName() string         { return this.CnName }
func (this *Field) SetCnName(v string) *Field { this.CnName = v; return this }
func (this *Field) GetReName() string         { return this.ReName }
func (this *Field) SetReName(v string) *Field { this.ReName = v; return this }
func (this *Field) GetType() string           { return this.Type }
func (this *Field) SetType(v string) *Field   { this.Type = v; return this }
func (this *Field) SetDir(v string) *Field    { this.JoinDir = v; return this }
func (this *Field) SetDesc(v string) *Field   { this.Desc = v; return this }
func (this *Field) SetNote(v string) *Field   { this.Note = v; return this }

func (this *Field) IsString() *Field      { this.Type = F_STRING; return this }
func (this *Field) IsInt() *Field         { this.Type = F_INT; return this }
func (this *Field) IsFloat() *Field       { this.Type = F_FLOAT; return this }
func (this *Field) IsBool() *Field        { this.Type = F_BOOL; return this }
func (this *Field) IsTime() *Field        { this.Type = F_TIME; return this }
func (this *Field) IsArrayInt() *Field    { this.Type = F_A_INT; return this }
func (this *Field) IsArrayFloat() *Field  { this.Type = F_A_FLOAT; return this }
func (this *Field) IsArrayString() *Field { this.Type = F_A_STRING; return this }
func (this *Field) IsPic() *Field         { this.Type = F_PIC; return this }
func (this *Field) IsPics() *Field        { this.Type = F_PICS; return this }
func (this *Field) IsFile() *Field        { this.Type = F_FILE; return this }
func (this *Field) IsFiles() *Field       { this.Type = F_FILES; return this }

func (this *Field) IsAny(anyType string) *Field { this.Type = anyType; return this }

func (this *Field) IsJoinM2O(joinDoc string, keys ...string) *Field {
	this.JoinDoc = joinDoc
	this.JoinType = "O"
	this.Type = F_O2O + joinDoc
	for i, key := range keys {
		if i == 0 {
			//keyInside
			this.KeyInside = key
		}
		if i == 1 {
			//keyOutSide
			this.KeyOutSide = key
		}
	}
	if this.KeyInside == "" {
		this.KeyInside = fmt.Sprintf("%sId", this.Name)
	}
	if this.KeyOutSide == "" {
		this.KeyOutSide = "id"
	}

	return this
}
func (this *Field) IsJoinO2M(joinDoc string, keys ...string) *Field {
	this.JoinDoc = joinDoc
	this.JoinType = "M"
	this.Type = F_O2M + joinDoc
	for i, key := range keys {
		if i == 0 {
			//keyInside
			this.KeyInside = key
		}
		if i == 1 {
			//keyOutSide
			this.KeyOutSide = key
		}
	}
	if this.KeyInside == "" {
		this.KeyInside = "id"
	}
	if this.KeyOutSide == "" {
		this.KeyOutSide = fmt.Sprintf("%sIds", this.Name)
	}
	return this
}
func (this *Field) IsJoinM2M(joinDoc string, keys ...string) *Field {
	this.JoinDoc = joinDoc
	this.JoinType = "MM"
	this.Type = F_O2M + joinDoc
	for i, key := range keys {
		if i == 0 {
			//keyInside
			this.KeyInside = key
		}
		if i == 1 {
			//keyOutSide
			this.KeyOutSide = key
		}
	}
	if this.KeyInside == "" {
		this.KeyInside = fmt.Sprintf("%sIds", this.Name)
	}
	if this.KeyOutSide == "" {
		this.KeyOutSide = "id"
	}
	return this
}

//todo IsJoinM2M
